package com.yh.filesystem.service;

import com.alibaba.fastjson.JSON;
import com.lxw.framework.domain.filesystem.FileSystem;
import com.lxw.framework.domain.filesystem.response.FileSystemCode;
import com.lxw.framework.domain.filesystem.response.UploadFileResult;
import com.lxw.framework.exception.ExceptionCase;
import com.lxw.framework.model.response.CommonCode;
import com.yh.filesystem.dao.FilesystemRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Map;

/**
 * @AUTHOR: yadong
 * @DATE: 2021/7/19 15:38
 * @DESC:
 */
@Service
@Slf4j
public class FilesystemService {

    @Value("${yh.fastdfs.tracker_servers}")
    private String tracker_servers;

    @Value("${yh.fastdfs.connect_timeout_in_seconds}")
    private Integer connect_timeout_in_seconds;

    @Value("${yh.fastdfs.network_timeout_in_seconds}")
    private Integer network_timeout_in_seconds;

    @Value("${yh.fastdfs.charset}")
    private String charset;

    @Autowired
    private FilesystemRepository filesystemRepository;

    public UploadFileResult uploadFile(MultipartFile file, String businesskey, String filetag, String metadata) {
        //校验必要参数
        if(file == null){
            ExceptionCase.cast(FileSystemCode.FS_UPLOADFILE_FILEISNULL);
        }
        // 把文件上传到fastDfs
        String fileId = this.uploadFile2Fastdfs(file);
        if(StringUtils.isEmpty(fileId)){
            ExceptionCase.cast(FileSystemCode.FS_UPLOADFILE_SERVERFAIL);
        }
        //把上传成功的文件信息保存到mongoDb中
        FileSystem fileSystem = this.saveFileSystem(file, businesskey, filetag, metadata, fileId);

        return new UploadFileResult(CommonCode.SUCCESS,fileSystem);
    }

    //把上传成功的文件信息保存到mongoDb中
    private FileSystem saveFileSystem(MultipartFile file,String businesskey, String filetag, String metadata,String fileId){
        //封装fileSystem对象
        FileSystem fileSystem = new FileSystem();
        fileSystem.setBusinesskey(businesskey);
        fileSystem.setFileId(fileId);
        fileSystem.setFileName(file.getOriginalFilename());
        fileSystem.setFileSize(file.getSize());
        fileSystem.setFilePath(fileId);
        fileSystem.setFiletag(filetag);
        if(StringUtils.isNotEmpty(metadata)){
            Map map = JSON.parseObject(metadata, Map.class);
            fileSystem.setMetadata(map);
        }

        //执行保存
        filesystemRepository.insert(fileSystem);
        return fileSystem;
    }

    // 把文件上传到fastDfs
    private String uploadFile2Fastdfs(MultipartFile file){
        initConfig();

        try {
            //
            TrackerClient trackerClient = new TrackerClient();
            //
            TrackerServer trackerServer = trackerClient.getConnection();
            //
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            //
            StorageClient1 storageClient1 = new StorageClient1(trackerServer,storageServer);
            //
            //获取mulitipartFile的字节数组
            byte[] bytes = file.getBytes();
            String originalFilename = file.getOriginalFilename();
            String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            String fileId = storageClient1.upload_file1(bytes, ext, null);
            return fileId;
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            ExceptionCase.cast(FileSystemCode.FS_UPLOADFILE_SERVERFAIL);
        }
        return null;
    }

    //初始化参数
    private void initConfig(){
        //加载配置
        try {
            ClientGlobal.initByTrackers(tracker_servers);
            ClientGlobal.setG_charset(charset);
            ClientGlobal.setG_connect_timeout(connect_timeout_in_seconds);
            ClientGlobal.setG_network_timeout(network_timeout_in_seconds);
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            ExceptionCase.cast(FileSystemCode.FS_UPLOADFILE_SERVERFAIL);
        }
    }


}
